<template>
    <div class="rank-box">
        <div class="rank-header">
            <el-text :size="isH5 ? 'small' : 'default'">
                注：当前界面只展示代码题的实时成绩，不展示非代码题的实时成绩。赛中成绩仅作参考，不作为最终成绩依据。
            </el-text>
            <div>
                <el-button class="refresh" :size="isH5 ? 'small' : 'default'" type="primary" @click="start">刷新</el-button>
            </div>
        </div>
        <el-table class="match-rank-table" :data="tableData" style="width: 100%" :max-height="`calc(100vh - 24px)`"
            :size="isH5 ? 'small' : 'default'">
            <template v-slot:empty>
                <el-empty image="https://cdn-hterobot.oss-cn-qingdao.aliyuncs.com/image/ojSass-empty.png" />
            </template>
            <el-table-column type="index" label="排名" align="center" :width="isH5 ? 50 : 80" fixed></el-table-column>
            <el-table-column prop="username" label="成员" align="center" :width="isH5 ? 120 : 150" fixed
                show-overflow-tooltip>
                <template #default="{ row }">
                    <template v-if="p.nameDisplayMode === 'ojSass'">
                        {{ row.name }}
                        {{ row.xingming ? row.name === row.xingming ? '' : `(${row.xingming})` : '' }}
                    </template>
                    <template v-else>
                        {{ row.xingming ? `${row.xingming} (${row.name})` : row.name }}
                    </template>
                </template>
            </el-table-column>
            <el-table-column prop="df" label="总分" align="center" :width="isH5 ? '' : 100" fixed sortable>
                <template #default="{ row }">
                    <div v-if="!p.simpleMode">
                        {{ showScoreColumn ? row?.df : '-' }}
                    </div>
                    <div v-else>
                        {{ row.df }}
                    </div>
                </template>
            </el-table-column>
            <el-table-column v-for="(item, key) in matchQuestion" :key="key" align="center" :prop="String(key)" width=""
                class-name="el-table-column" label-class-name="match-rank-table-header">
                <template #header="{ row }">
                    <el-tooltip effect="dark" :content="item.name" placement="top">
                        <div class="AC-detail">
                            <div class="match-rank-table-header-qNo">
                                {{ `# ${key + 1}` }}
                            </div>
                            <div class="match-rank-table-header-qScore">
                                {{ `${item.score}` }}
                            </div>
                        </div>
                    </el-tooltip>
                </template>
                <template v-if="p.simpleMode">
                    <template #default="{ row: { rank } }">
                        <div :class="className(rank, item, key)">
                            {{ rank[key].score }}
                        </div>
                    </template>
                </template>
                <template v-else>
                    <el-table-column label="得分" align="center" :width="90">
                        <template #default="{ row: { rank, userquestion } }">
                            <div v-if="showScoreColumn" :class="className(rank, item, key)">
                                {{ rank[key].score }}
                            </div>
                            <div v-else> {{ rank[key].answered ? '已提交' : '未提交' }}</div>
                        </template>
                    </el-table-column>
                    <el-table-column label="测试点" align="center" show-overflow-tooltip width="">
                        <template #default="{ row: { rank, userquestion } }">
                            <div v-if="showDetailedScore" class="AC-detail">
                                <el-tag class="question-intable-label" effect="dark"
                                    :class="['bg-' + getResultMeta(userquestion, key).className, 'margin-left10']">
                                    {{ getResultMeta(userquestion, key).label }}
                                </el-tag>
                                <span v-if="showDetailedScore && Array.isArray(userquestion?.resultdataarr[key])">
                                </span>
                            </div>
                            <div v-else> - </div>
                        </template>
                    </el-table-column>
                </template>
            </el-table-column>
        </el-table>
    </div>
</template>

<script setup lang="ts">
import { countBy } from 'lodash-es';
import { pairs } from 'underscore';
import { computed, onMounted, reactive, ref, watch } from 'vue';
import { useRouter } from "vue-router";
import { useStore } from "vuex";
import { asyncgetactivity, asyncselectmatchquestion, asyncselectmatchranking } from "@/api";
import { Storekey } from "@/interface";
import Studycodemodel from "@/mysql_interface/studycodemodel";
import { SHOW_AC_STATUS } from '@/admin/views/data';
import { ALLTYPE } from '@/util/jianchatime';

type P = {
    activity: Studycodemodel.Iactivity,
    simpleMode?: boolean, // mathH5, acCoderH5
    isH5?: boolean, // acCoderH5
    nameDisplayMode?: 'ojSass' | 'default' // ojSass, mathH5
}
const p = withDefaults(defineProps<P>(), {
    simpleMode: false,
    isH5: false,
    nameDisplayMode: 'default'
})

const router = useRouter();
const store = useStore(Storekey)
const user = computed(() => {
    return store.state.user
})

const limit = ref(1000)
const offset = ref(0)
const activity = reactive<Studycodemodel.Iactivity>({});
const format = computed(() => {
    return p.activity.format
})

watch(() => p.activity.ID, (v) => {
    if (v) start()
})

onMounted(async () => {
    if (p.simpleMode) {
        if (!p.activity.isranking) return
        if (format.value === "OI") return;
    } else {
        if (!p.activity.isrank) return
    }

    await start()
    // 进入房间
    store.state.socket.emit("activity", { activityid: p.activity.ID, com: true });
    store.state.socket.on("activity", () => {
        console.log("socket.on activity")
        getMatchRanking()
    })
})

async function start() {
    if (p.activity.ID) {
        const data = await asyncgetactivity({ ID: p.activity.ID });
        Object.assign(activity, data);
    }
    getMatchRanking()
    selectmatchquestion()
}

const matchQuestion = ref<Studycodemodel.Imatchquestion[]>([{ score: 0 }])
async function selectmatchquestion() {
    const [data] = await asyncselectmatchquestion({ activityid: p.activity.ID })
    matchQuestion.value = data.matchquestion || []
}

const users = ref<Studycodemodel.Iuser[]>([])
const matchRanking = ref<Studycodemodel.Imatchranking[]>([])
async function getMatchRanking() {
    const { user, matchranking } = await asyncselectmatchranking({
        activityid: p.activity.ID,
        _offset: offset.value, _limit: limit.value, _order: 'df', _sortable: 'DESC'
    })
    users.value = user
    matchRanking.value = matchranking
}

// 组装数据
const tableData = computed(() => {
    const ret = users.value.map(u => {
        let rank: { type: string, score: number, answered?: boolean }[] = []
        const { ID } = u
        const matchranking = matchRanking.value.find(e => e.userid === ID) || {}
        const _data = JSON.parse(matchranking?.data || '') as any[]

        rank = matchQuestion.value.map((e, i) => {
            const answered = _data.find(z => z[2] === e.name)
            let score = answered ? (answered[1] || 0) : '-'
            if (e.type !== '代码') {
                score = answered ? '完成' : '-'
            }
            return {
                type: e.type,
                score,
                answered: !!answered
            }
        })

        const resultdata = _data.map(e => e[3]).filter(e => e === 'AC').length === _data.length ? 'AC' : 'UN'

        if (p.simpleMode) {
            return {
                rank,
                ...u,
                ...matchranking,
                resultdata
            }
        }

        const userquestion = {
            resultdataarr: _data.map(question => {
                const testCases = question[4] || [];
                return testCases.map(testCase => testCase[3]);
            }),
            resultdata: _data.map(e => e[3])
        }

        return {
            rank,
            ...u,
            ...matchranking,
            resultdata,
            userquestion,
        }
    }).sort((a, b) => Number(b.df) - Number(a.df))
    return ret
})

function className(rank: { type: string, score: number }[], matchquestion: Studycodemodel.Imatchquestion, index: number) {
    const n = rank[index].score
    if (isNaN(n)) return
    const c = n / Number(matchquestion.score)
    if (c >= 0.7) {
        return 'Accepted'
    } else if (c >= 0.3) {
        return 'Unaccepted'
    } else {
        return 'CompileError'
    }
}

// 根据配置
const showScoreColumn = computed(() => {
    return activity?.show_ac_status === SHOW_AC_STATUS.SHOW_SCORE || activity?.show_ac_status === SHOW_AC_STATUS.SHOW_DETAILED_SCORE;
})

const showDetailedScore = computed(() => {
    return activity?.show_ac_status === SHOW_AC_STATUS.SHOW_DETAILED_SCORE
})

function getResultMeta(userquestion: { resultdataarr: any[]; resultdata: any[] }, index: number) {
    const mode = activity?.show_ac_status;
    let label = '-', className = 'WT';
    if (!userquestion) return { label, className };
    if (index === undefined || index === null || index < 0 || index >= userquestion.resultdata.length) {
        return { label, className };
    }
    const currentResultArr = userquestion.resultdataarr?.[index] || [];
    const currentResult = userquestion.resultdata?.[index];

    if (mode === SHOW_AC_STATUS.SHOW_FULL_AC) {
        const allAC = currentResultArr.length > 0 ? currentResultArr.every(v => v === 'AC') : false;
        className = allAC ? 'AC' : 'UN';
        label = allAC ? '通过' : '未通过';
    } else {
        className = currentResult || 'UN';
        label = ALLTYPE[className]?.[1] || '未通过';
    }
    return {
        label,
        className: ALLTYPE[className]?.[1] || 'WT'
    };
}
</script>

<style scoped>
.rank-box {
    margin: 0;
    --rank-header-height: 40px;
}

.rank-header {
    display: flex;
    justify-content: space-between;
    height: var(--rank-header-height);
    align-items: center;
}

.refresh {
    border-radius: 5px;
}

.match-rank-table-header-qNo,
.match-rank-table-header-qScore {
    position: relative;
}

.match-rank-table-header-qScore {
    color: #7f7f7f;
}
</style>
